package net.maku.kyy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import net.maku.framework.common.constant.Constant;
import net.maku.framework.common.constant.MessageConstant;
import net.maku.framework.common.exception.ServerException;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.framework.security.utils.ThreadLocalUtil;
import net.maku.kyy.constant.KyyConstant;
import net.maku.kyy.constant.KyyRedisKeyConstant;
import net.maku.kyy.convert.KyyForumReplayConvert;
import net.maku.kyy.entity.KyyForumReplayEntity;
import net.maku.kyy.query.KyyForumReplayQuery;
import net.maku.kyy.utils.GetUserMessageUtil;
import net.maku.kyy.vo.KyyForumReplayVO;
import net.maku.kyy.dao.KyyForumReplayDao;
import net.maku.kyy.service.KyyForumReplayService;
import com.fhs.trans.service.impl.TransService;
import net.maku.framework.common.utils.ExcelUtils;
import net.maku.kyy.vo.KyyForumReplayExcelVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 回复表
 *
 * @author MAKU babamu@126.com
 * <a href="https://maku.net">MAKU</a>
 */
@Service
@AllArgsConstructor
public class KyyForumReplayServiceImpl extends BaseServiceImpl<KyyForumReplayDao, KyyForumReplayEntity> implements KyyForumReplayService {
    private final TransService transService;
    @Autowired
    private KyyForumReplayDao kyyForumReplayDao;
    @Autowired
    private KyyForumServiceImpl kyyForumService;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    @Override
    public PageResult<KyyForumReplayVO> page(KyyForumReplayQuery query) {
        IPage<KyyForumReplayEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));

        return new PageResult<>(KyyForumReplayConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
    }


    private LambdaQueryWrapper<KyyForumReplayEntity> getWrapper(KyyForumReplayQuery query){
        LambdaQueryWrapper<KyyForumReplayEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ObjectUtil.isNotEmpty(query.getId()), KyyForumReplayEntity::getId, query.getId());

        wrapper.eq(ObjectUtil.isNotEmpty(query.getForumid()), KyyForumReplayEntity::getForumid, query.getForumid());
        wrapper.eq(ObjectUtil.isNotEmpty(query.getOpenid()), KyyForumReplayEntity::getOpenid, query.getOpenid());
        wrapper.orderByDesc( KyyForumReplayEntity::getCreateTime);

        return wrapper;
    }


    @Override
    public KyyForumReplayVO get(Long id) {
        KyyForumReplayEntity entity = baseMapper.selectById(id);
        KyyForumReplayVO vo = KyyForumReplayConvert.INSTANCE.convert(entity);

        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(KyyForumReplayVO vo) {
        KyyForumReplayEntity entity = KyyForumReplayConvert.INSTANCE.convert(vo);

        baseMapper.insert(entity);


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(KyyForumReplayVO vo) {
        KyyForumReplayEntity entity = KyyForumReplayConvert.INSTANCE.convert(vo);

        updateById(entity);


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> idList) {
        removeByIds(idList);

    }



    @Override
    public void export() {
    List<KyyForumReplayExcelVO> excelList = KyyForumReplayConvert.INSTANCE.convertExcelList(list());
        transService.transBatch(excelList);
        ExcelUtils.excelExport(KyyForumReplayExcelVO.class, "回复表", null, excelList);
    }

    /**
     * 查询与我相关的评论
     * @param query
     * @return
     */
    @Override
    public PageResult<KyyForumReplayVO> replayAboutMe(KyyForumReplayQuery query) {
        Map map=ThreadLocalUtil.get();
        if (map==null){
            throw new RuntimeException("请先登录");
        }
        Long userId=(Long)map.get(Constant.KYY_USER_ID);
        if (userId==null){
            throw new RuntimeException("请先登录");
        }
        //根据userId查询关于我的评论
        IPage<KyyForumReplayEntity> page = kyyForumReplayDao.selectReplayAboutMe(getPage(query), userId, query);
        return new PageResult<>(KyyForumReplayConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
    }

    /**
     * 发布评论
     *
     * 评论封禁管控方案：封禁时间：5分钟，封禁原因：频繁发布评论，请勿发布违法内容，。
     * 正常5秒内发布一次评论
     * 若5秒内发送发布请求超过20次，封禁1分钟，封禁原因：频繁发布评论
     * 使用hash存储对应count和time，key:user:userId:record
     * 封禁的key：kyy:user:userId:replay:ban
     * @param vo
     */
    @Transactional
    @Override
    public void comment(KyyForumReplayVO vo) {
        KyyForumReplayEntity kyyForumReplayEntity = BeanUtil.copyProperties(vo, KyyForumReplayEntity.class);
        kyyForumReplayDao.insert(kyyForumReplayEntity);
        //添加
        Integer forumid = kyyForumReplayEntity.getForumid();
        //修改评论数
        kyyForumService.updateNum2(forumid);
//        Long userId = GetUserMessageUtil.getUserId();
//        //kyy:user:用户id:replay:ban
//        String banKey=KyyRedisKeyConstant.KYY_USER+":"+userId+KyyRedisKeyConstant.REPLAY_BAN;
//        //查询用户的评论功能是否处于封禁状态
//        isReplayBan(banKey);
//        //查询用户5秒内评论次数是否超过20次，封禁5分钟
//        //kyy:user:用户id:replay:count
//        String key=KyyRedisKeyConstant.KYY_USER+":"+userId+KyyRedisKeyConstant.REPLAY_COUNT;
//        //判断评论缓存是否存在
//        if (redisTemplate.hasKey(key)){
//            //获取key剩余的时间
//            Long expire = redisTemplate.getExpire(key, TimeUnit.SECONDS);
//            //存在
//            Long replayCount = Long.valueOf(redisTemplate.opsForValue().get(key));
//            if (replayCount>KyyConstant.REPLAY_BAN_NUM){
//                //达到封禁次数
//                redisTemplate.opsForValue().set(banKey,Constant.COMMENT_BAN_REASON,5, TimeUnit.MINUTES);
//                redisTemplate.delete(key);
//                throw new ServerException(MessageConstant.REPLAY_BAN);
//            }
//            //频繁时间过后才能评论
//            if (replayCount!=null){
//                //删除重新添加缓存
////                redisTemplate.delete(key);
//                //修改缓存
//                redisTemplate.opsForValue().set(key, String.valueOf(replayCount+1),expire, TimeUnit.SECONDS);
//                //提醒
//                throw new ServerException(MessageConstant.REPLAY_FREQUENTLY);
//            }
//        }
//
//        try {
//            KyyForumReplayEntity kyyForumReplayEntity = BeanUtil.copyProperties(vo, KyyForumReplayEntity.class);
//            kyyForumReplayEntity.setCreator(userId);
//            kyyForumReplayEntity.setUpdater(userId);
//            kyyForumReplayDao.insert(kyyForumReplayEntity);
//            //添加
//            Integer forumid = kyyForumReplayEntity.getForumid();
//            //修改评论数
//            kyyForumService.updateNum2(forumid);
//            //添加评论频繁时间缓存
//            redisTemplate.opsForValue().set(key,Constant.REPLAY_COUNT_INIT,50, TimeUnit.SECONDS);
//        } catch (Exception e) {
//            throw new ServerException(MessageConstant.PUSH_COMMENT_FAIL);
//        }

    }


    /**
     * 查看回复功能是否被封禁
     * @param key
     * @return true:封禁 false:未封禁
     */
    public boolean isReplayBan(String key){
        if (redisTemplate.hasKey(key)){
            //存在 代表被封禁
            throw new ServerException(MessageConstant.REPLAY_BAN);
        }
        return false;
    }




}